<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
<!--    <meta charset="UTF-8" />-->
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Spitter</title>
    <link rel="stylesheet" type="text/css" th:href="@{/resources/style.css}" />
</head>
<body>
    <form method="post" th:object="${spitter}">
        <!-- <div> 元素使用 th:if 属性来检查是否有校验错误。如果有的话，会渲染 <div>，否则的话，它将不会渲染。 -->
        <div class="errors" th:if="${#fields.hasErrors('*')}">
            <ul>
                <!-- <li> 标签上的 th:each 属性将会通知 Thymeleaf 为每项错误都渲染一个 <li>，在每次迭代中会将当前错误设置到一个名为 err 的变量中。 -->
                <!-- <li> 标签还有一个 th:text 属性。这个命令会通知 Thymeleaf 计算某一个表达式（在本例中，也就是 err 变量）并将它的值渲染为 <li>
                 标签的内容体。实际上的效果就是每项错误对应一个 <li> 元素，并展现错误的文本。 -->
                <li th:each="err : ${#fields.errors('*')}" th:text="${err}">Input is incorrect</li>
            </ul>
        </div>
        <!-- th:class 属性会渲染为一个 class 属性，它的值是根据给定的表达式计算得到的。在下面的这两个 th:class 属性中，
         它会直接检查 firstName 域有没有校验错误。如果有的话，class 属性在渲染时的值为 error。如果这个域没有错误的话，
         将不会渲染 class 属性。 -->
        <!-- “${}” 表达式（如${spitter}）是变量表达式（variable expression）。一般来讲，它们会是对象图导航
        语言（Object-GraphNavigation Language，OGNL）表达式（http://commons.apache.org/proper/commons-ognl/）。但在使用 Spring 的时候，
        它们是 SpEL 表达式。在 ${spitter} 这个例子中，它会解析为 key 为 spitter 的 model 属性。 -->
        <label th:class="${#fields.hasErrors('firstName')}?'error'">First Name</label>：
        <!-- <input> 标签使用了 th:field 属性，用来引用后端对象的 firstName 域。这可能与你的预期有点差别。在 Thymeleaf 模板中，
         我们在很多情况下所使用的属性都对应于标准的 HTML 属性，因此貌似使用 th:value 属性来设置 <input> 标签的 value 属性才是合理的。
         其实不然，因为我们是在将这个输入域绑定到后端对象的 firstName 属性上，因此使用 th:field 属性引用 firstName 域。通过使用 th:field，
         我们将 value 属性设置为 firstName 的值，同时还会将 name 属性设置为 firstName。-->
        <!-- 对于 “*{}” 表达式，它们是选择表达式（selection expression）。变量表达式是基于整个 SpEL 上下文计算的，而选择表达式是基于某一
         个选中对象计算的。在本例的表单中，选中对象就是 <form> 标签中 th:object 属性所设置的对象：模型中的 Spitter 对象。因此，“*{firstName}” 表达式
         就会计算为 Spitter 对象的 firstName 属性。 -->
        <input type="text" th:field="*{firstName}" th:class="${#fields.hasErrors('firstName')}? 'error'" /><br/>
        <label th:class="${#fields.hasErrors('lastName')}? 'error'">Last Name</label>：
        <input type="text" th:field="*{lastName}" th:class="${#fields.hasErrors('lastName')}? 'error'" /><br/>
        <label th:class="${#fields.hasErrors('username')}? 'error'">Username</label>：
        <input type="text" th:field="*{username}" th:class="${#fields.hasErrors('username')}? 'error'" /><br/>
        <label th:class="${#fields.hasErrors('password')}? 'error'">Password</label>：
        <input type="password" th:field="*{password}" th:class="${#fields.hasErrors('password')}? 'error'" /><br/>
        <input type="submit" value="Register" />
    </form>
</body>
</html>